-
Notifications
You must be signed in to change notification settings - Fork 27.4k
fix($location/$browser): prevent infinite digests on empty hash changes #9923
Conversation
Actually @lgalfaso - here is one that you could review for me. |
There is one thing that I do not fully like about this patch. Even when This is, by adding a |
AFAIK: moving from
|
I believe that @tbosch is correct. This is the main cause of the problem. When we go from a URL with a hash to one without the browser does a page reload but doesn't update the location.href (since the page will be reloading anyway - it believes). In non-HTML5 mode we always leave a # symbol in place so the page does not reload. In this case, I don't think that this fix is a breaking change unless someone is trying to force a page reload by removing the hash from the URL. Previously removing the hash would cause a page reload and so the browser would reset to the top of the page anyway. The workaround if you intended to reload the page would be to add an additional call to What do you think? |
@petebacondarwin is this still the case when we do not really go to the page but just push the new url to the browser history? One more question: Will people think that always adding a |
@@ -68,6 +68,10 @@ function stripHash(url) { | |||
return index == -1 ? url : url.substr(0, index); | |||
} | |||
|
|||
function trimEmptyHash(url) { | |||
return url.replace(/#$/,''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will not do the right thing for URLs of the form http://example.com/foo#bar#
(check that there are two #
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Good point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although strictly unescaped # characters are not allowed inside fragments, I guess we have to deal with that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that strictly speaking, this is not supported, but I tested this with Chrome and Safari and in both cases location.hash was unescaped
Good question. I was wondering about this myself. I think we could try to be clever and only add the empty hash in if we are moving to a URL that has the same base and no hash, while the original did have a hash fragment? |
@petebacondarwin if the |
I will try to implement that tomorrow but unfortunately I am running a workshop all day so I might miss the 1.3.2 cut-off |
Hey there, I just wanted to mention that this seems to happen when you navigate to any URL with an empty hash, not just when making a change. It might already be covered by this fix, but I'm not sure - the test cases seem to test things like |
This does appear to be fixed by this: https://ci.angularjs.org/job/angular.js-pete/711/artifact/build/docs/api# |
OK good 😄 |
@lgalfaso - actually this is what the code already does! Do we really need to cope with unescaped |
There is one case which is fixed by #9903, but not by this PR:
I don't know if the previous behavior was explicitly supported, but it made sense to me, since initial loading of a site works without |
The main issue is that the browser does not escape the second |
@lgalfaso - OK, I will change the regex. |
By retaining a trailing `#` character in the URL we ensure that the browser does not attempt a reload, which in turn allows us to read the correct `location.href` value. Closes angular#9635
The url is the same whether or not there is an empty `#` marker at the end. This prevents unwanted calls to update the browser, since the browser is automatically applying an empty hash if necessary to prevent page reloads. Closes angular#9635
The test for not rewriting links was invalid and just happened to be passing by chance (false-positive).
I believe that this link should be rewritten to In other words, is this test actually invalid: https://github.com/angular/angular.js/blob/master/test/ng/locationSpec.js#L1972-L1978 it("should not set hash if one was not originally specified", function() {
location = new LocationHashbangUrl('http://server/pre/index.html', '#');
location.$$parse('http://server/pre/index.html');
expect(location.url()).toBe('');
expect(location.absUrl()).toBe('http://server/pre/index.html');
}); |
55ba752
to
a2be4b1
Compare
Actually, @Narretz - this PR doesn't actually have the problem you describe. See https://gist.github.com/petebacondarwin/3a3bab60cb00941874f4 |
@petebacondarwin Okay, I will test again and see what the difference between your gist and my test is. |
In my Gist, the browser actually does a reload - because the new URL without the hash bang is treated as outside the app. Is this desired? It seems to me that this is about right. If you want to stay within the application you should include the hash bang. But this may not be what people expect. |
Is this also the case in html5 mode? |
@lgalfaso - so in HTML5 mode it is a little different as we have no hash-bang situation but it does appear that going from |
OK, so that reload does not happen in 1.2.20 so it should not happen here. It may be that a variant on #9903 is better |
LGTM |
This doesn't actually fully solve the problem either. Check back on #9635 for further analysis |
Fixes #9635